package com.example.compose

import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round

@Composable
fun SwipeableCard(color: Color, offset: Float, scale: Float, action: () -> Unit) {
    var dragging by remember {
        mutableStateOf(false)
    }
    var dragOffset by remember {
        mutableStateOf(Offset.Zero)
    }
    val animatedOffset by animateOffsetAsState(
        targetValue = when {
            dragging -> Offset(0f, offset) + dragOffset
            else -> Offset(0f, offset)
        },
        animationSpec = if (dragging) snap() else spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        ),
        label = ""
    )
    val animatedScale by animateFloatAsState(targetValue = scale, label = "card scale")
    Box(
        modifier = Modifier
            .offset { animatedOffset.round() }
            .scale(scale = animatedScale)
            .width(200.dp)
            .height(300.dp)
            .clip(RoundedCornerShape(16.dp))
            .background(color = color)
            .pointerInput(Unit) {
                detectDragGestures(
                    onDragStart = {
                        dragOffset = Offset.Zero
                        dragging = true
                    },
                    onDragEnd = {
                        dragging = false
                        action()
                    },
                    onDrag = { change, dragAmount ->
                        change.consume()
                        dragOffset += dragAmount
                    }
                )
            }
    )
}

@Preview
@Composable
private fun SwipeableStackPreview() {
    var state by remember {
        mutableStateOf(
            listOf(
                Color.Red,
                Color.Yellow,
                Color.Gray,
                Color.Blue,
                Color.Green,
                Color.Magenta
            )
        )
    }
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(color = MaterialTheme.colorScheme.background),
        contentAlignment = Alignment.Center
    ) {
        state.forEachIndexed { index, color ->
            key(color) {
                val reversed = state.lastIndex - index
                val offset = reversed * -30f
                val scale = 1f - reversed / 30f
                SwipeableCard(color = color, offset = offset, scale = scale) {
                    state = listOf(color) + (state - color)
                }
            }
        }
    }
}

fun main() {
    var state  = listOf(1,2,3,4,5)
    state.forEachIndexed { index, i ->
        state = listOf(i) + (state - i)
        println(state)
    }
}